package com.smdp.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.smdp.dto.ChangePasswordFormDTO;
import com.smdp.dto.LoginFormDTO;
import com.smdp.dto.Result;
import com.smdp.entity.User;

import javax.servlet.http.HttpServletRequest;

/**
 * 用户功能服务接口。
 * 包含发送（登录和修改密码的）验证码、登录（使用验证码或密码）、修改密码（使用验证码或密码）、查询“我的信息”、登出、根据用户id查询用户、签到
 * 以及查询连续签到天数。其中，发送验证码通过阿里云短信服务实现，验证码保存在Redis中；数据库只储存加盐加密的密码，防止用户密码泄露；
 * 根据id查询用户信息仅返回不敏感的信息，防止用户敏感信息泄露。
 *
 * @author 蔡方珩
 */
public interface IUserService extends IService<User> {
    /**
     * 发送登录的手机验证码。
     * 通过阿里云服务实现短信发送，并将验证码保存在Redis中等待比对。
     * @param phone 电话号码
     * @return 成功：ok / 失败：失败原因
     */
    Result sendCodeForLogin(String phone);
    /**
     * 使用验证码用户登录。
     * 将用户提供的验证码与Redis中的验证码比对。
     * @param loginForm 登录表单，包含用户手机和验证码
     * @return 登录成功：token / 登录失败：失败原因
     */
    Result loginByCode(LoginFormDTO loginForm);
    /**
     * 用户签到。
     * 使用Redis的BitMap储存签到信息。
     * @return ok
     */
    Result sign();
    /**
     * 统计用户连续签到天数。
     * 从BitMap中获取信息后统计天数。
     * @return 连续签到天数
     */
    Result signCount();
    /**
     * 登出
     * @param request http请求
     * @return ok
     */
    Result logout(HttpServletRequest request);
    /**
     * 使用密码登录。
     * 将用户提供的密码加盐加密，并与数据库中的密码进行比对。
     * @param loginForm 登录表单，包含用户手机和密码
     * @return 登录成功：token / 登录失败：失败原因
     */
    Result loginByPassword(LoginFormDTO loginForm);
    /**
     * 通过旧密码修改密码。
     * 通过验证后将加盐加密的密码加入数据库。修改成功后登出。
     * @param changePasswordForm 修改密码表单
     * @param request http请求
     * @return 登录成功：ok / 登录失败：失败原因
     */
    Result changePasswordByOldPassword(ChangePasswordFormDTO changePasswordForm, HttpServletRequest request);
    /**
     * 根据id查询用户信息。
     * @param userId 用户id
     * @return 成功：脱敏的用户信息 / 失败：ok
     */
    Result queryUserById(Long userId);
    /**
     * 发送修改密码的手机验证码
     * 通过阿里云服务实现，并将验证码保存在session中等待比对。
     * @param phone 电话号码
     * @return 成功：ok / 失败：失败原因
     */
    Result sendCodeForChangePassword(String phone);
    /**
     * 通过验证码修改密码。
     * 通过验证后将加盐加密的密码加入数据库。修改成功后登出。
     * @param changePasswordForm 修改密码表单
     * @param request http请求
     * @return 登录成功：ok / 登录失败：失败原因
     */
    Result changePasswordByCode(ChangePasswordFormDTO changePasswordForm, HttpServletRequest request);
}
